package com.googlecode.tidej.client.tree;

import java.util.ArrayList;

import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.googlecode.tidej.client.TidejController;
import com.googlecode.tidej.shared.model.Artifact;
import com.googlecode.tidej.shared.model.Library;
import com.googlecode.tidej.shared.model.Model;
import com.googlecode.tidej.shared.model.Operation;
import com.googlecode.tidej.shared.model.Property;
import com.googlecode.tidej.shared.model.Type;


public class ClassTree extends Composite {

  ScrollPanel scrollPanel;
  Model model;
  CellTree tree;
  TidejController controller;
  ClassTreeModel treeModel;
  
  public ClassTree(final TidejController controller) {
    this.controller = controller;
    this.model = controller.getModel();
    treeModel = new ClassTreeModel(controller);
    scrollPanel = new ScrollPanel();
    initWidget(scrollPanel);
    refresh();
  }

  public void refresh(Object o) {
    ListDataProvider<Object> provider =  treeModel.dataProviderCache.get(o);
    if (provider != null) {
      int oldSize = provider.getList().size();
      ArrayList<Object> tmp = new ArrayList<Object>();
      treeModel.fillList(tmp, o);
      if (tmp.size() == 0 && oldSize > 0) {
        refresh();
        return;
      }

      treeModel.fillList(provider.getList(), o);
      provider.refresh();
    }
  }
    // ahrg
  public void refresh() {
    treeModel.dataProviderCache.clear();
    if (tree != null) {
        scrollPanel.remove(tree);
    }
    tree = new CellTree(treeModel, model);
    tree.setDefaultNodeSize(Integer.MAX_VALUE);
    scrollPanel.add(tree);
  }

  public void select(Artifact a) {
  //  Window.alert("Select: " + a);
    
    if(a instanceof Property) {
      a = ((Property) a).getOwner();
    }
    
    if (a instanceof Type) {
      openLibrary(a.getLibrary());
    } else if (a == controller.getProject()) {
      //
    } else if (a instanceof Library) {
      tree.getRootTreeNode().setChildOpen(1, true);
    } else if (a instanceof Operation) {
      openType(((Operation) a).getOwner());
    } 
    treeModel.selectionModel.setSelected(a, true);
  //  Window.alert("Selected: " + a);
  }

  private TreeNode openType(Type type) {
    TreeNode node = openLibrary(type.getLibrary());
    if (node != null) {
      for (int i = 0; i < node.getChildCount(); i++) {
        if (node.getChildValue(i) == type) {
          return node.setChildOpen(i, true);
        }
      }
    }
    return node;
  }
  
  private TreeNode openLibrary(Library l) {
    if (l == controller.getProject() && controller.getProject() != null) {
      return tree.getRootTreeNode().setChildOpen(0, true);
    } else {
      TreeNode node = tree.getRootTreeNode().setChildOpen(
          tree.getRootTreeNode().getChildCount() - 1, true);
      if (node != null) {
        for (int i = 0; i < node.getChildCount(); i++) {
          if (node.getChildValue(i) == l) {
            return node.setChildOpen(i, true);
          }
        }
      }
    }
    return null;      
  }
  
}
